package com.itrip.log.util;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.itrip.log.module.db.IDao;
import com.itrip.log.module.db.KVDB;
import com.itrip.log.module.db.domain.EmailGroup;
import com.itrip.log.module.db.domain.EmailRecord;
import com.itrip.log.module.db.server.ConfigManager;
import com.itrip.log.module.db.server.UserManager;

/**
 * Function:合并发送邮件
 * 
 * @author: jeff.cao@aoliday.com
 * @date: 2016年2月17日
 * 
 */
public class MailQueue implements Runnable {

	private KVDB kvdb;

	private IDao daoTemplate;

	private UserManager userManager;
	
	private ConfigManager cfgServer;

	private int maxLen = 1024 * 100;

	private long mergePerido = 1000 * 30;

	private String noticeUrl;

	private Logger log = LoggerFactory.getLogger(MailQueue.class);

	private Map<String, StringBuffer> queue = new HashMap<String, StringBuffer>();

	public String getNoticeUrl() {
		return noticeUrl;
	}

	public void setNoticeUrl(String noticeUrl) {
		this.noticeUrl = noticeUrl;
	}

	public void setKvdb(KVDB kvdb) {
		this.kvdb = kvdb;
	}

	public void setDaoTemplate(IDao daoTemplate) {
		this.daoTemplate = daoTemplate;
	}

	public void setUserManager(UserManager userManager) {
		this.userManager = userManager;
	}
	
	public void setCfgServer(ConfigManager cfgServer) {
		this.cfgServer = cfgServer;
	}

	public void setMergePerido(long mergePerido) {
		this.mergePerido = mergePerido;
	}

	public void setMaxLen(int maxLen) {
		this.maxLen = maxLen;
	}

	public KVDB getKvdb() {
		return kvdb;
	}

	public synchronized void addEmailTask(String emailGroup, String project, StringBuffer info, String keyword) {
		if (userManager.getEmail(emailGroup) == null)
			throw new RuntimeException("emailGroup is not exist:" + emailGroup);
		String key = emailGroup.concat("#").concat(project).concat("#").concat(keyword);
		StringBuffer buffer = queue.get(key);
		if (buffer == null) {
			buffer = info;
			queue.put(key, info);
		} else {
			buffer.append("<br>\n").append(info);
		}

		if (buffer.length() > maxLen) {
			this.notifyAll();
		}
	}

	public synchronized void start() {
		log.info("MailQueue:MailQueue started");
		Thread thread = new Thread(this);
		thread.setDaemon(true);
		thread.start();
	}

	@Override
	public void run() {
		Set<String> keywords = loadNotRecordKeyword();
		while (!Thread.interrupted()) {
			try {
				synchronized (this) {
					for (Entry<String, StringBuffer> entry : queue.entrySet()) {
						String[] key = entry.getKey().split("#");
						String emailGroup = key[0];
						String project = key[1];
						String keyword = key[2];
						saveEmailRecord(project, emailGroup, keyword, entry.getValue(), keywords);
					}
					queue.clear();
					wait(mergePerido);
				}
			} catch (Exception e) {
				log.error("error", e);
			}
		}
	}

	private Set<String> loadNotRecordKeyword() {
		Set<String> keywords = new HashSet<String>();
		JSONObject config = cfgServer.loadConfig("not_send_email");
		if (config != null) {
			Collection<Object> values = config.values();
			for (Object object : values) {
				String string = object.toString();
				String[] split = string.split(",");
				for (String kw : split) {
					keywords.add(kw);
				}
			}
		}
		log.info("not send email keyword:{}", keywords);
		return keywords;
	}

	private void saveEmailRecord(String project, String emalGroup, String keyword, StringBuffer value,
			Set<String> keywords) {
		long now = System.currentTimeMillis();
		String emailTitle = now + project;
		String string = value.toString();
		String manager = userManager.getManager(emalGroup);
		Set<EmailGroup> list = userManager.getEmail(emalGroup);
		boolean testNeedReord = testNeedReord(emalGroup, keywords, string);
		String pvStr = kvdb.hget("proc_pv",project);
		int pv = pvStr==null?-1:Integer.valueOf(pvStr);
		
		for (EmailGroup mail : list) {
			String email = mail.getEmail();
			Util.sendEmailHttp(noticeUrl, email, emailTitle, string);
			String key = String.valueOf(now).concat("_").concat(mail.getName());
			kvdb.put(key, string);
			if (testNeedReord) {
				EmailRecord rd = new EmailRecord();
				rd.setPv(pv);
				rd.setKvid(key);
				rd.setSendTime(now);
				rd.setManager(manager);
				rd.setProject(project);
				rd.setKeyword(keyword);
				rd.setName(mail.getName());
				daoTemplate.save("EmailRecord", rd);
			}
		}
		if (testNeedReord)
			log.info("send email:{} group:{}", list, emalGroup);
	}

	private boolean testNeedReord(String emalGroup, Set<String> keywords, String string) {
		for (String kw : keywords) {
			if (string.contains(kw)) {
				log.info("send group:{},but not record:{}", emalGroup, kw);
				return false;
			}
		}
		return true;
	}

}
